#ifndef CSE168_AREALIGHT_H_INCLUDED
#define CSE168_AREALIGHT_H_INCLUDED

#include "Miro.h"
#include <vector>
#include "Vector3.h"
#include "PointLight.h"
#include "Object.h"
#include "Sphere.h"
#include "AASquare.h"
#include "AARect.h"
#include "Ray.h"
#include "LightPath.h"
#include "LuminusMaterius.h"

class Scene;

class AreaLight
{
public:
	AreaLight()	{}
	virtual ~AreaLight(void) {}

    void setColor(const Vector3& v)     {m_color = v;}
    void setWattage(float f)            {m_wattage = f;}
    
    float wattage() const               {return m_wattage;}
    const Vector3 & color() const       {return m_color;}

	virtual void preCalc() 	{}

	virtual Vector3 sampleLight(const HitInfo &hit, const Scene &scene) = 0;
	virtual void tracePhoton(LightPath &lp, const Scene &scene) = 0;
	
protected:
	Vector3 m_color;
	float m_wattage;
	float m_area; // do we need this to scale the power per dA as wattage/area
};

typedef std::vector<AreaLight*> AreaLights;


class SphereLight : public AreaLight, public Sphere
{
public:
	SphereLight();
	virtual ~SphereLight();

	// cut off public access to this, since we always want material to be LuminusMaterius
	virtual void setMaterial(Material *material) {}

	virtual void preCalc();
	
	virtual Vector3 sampleLight(const HitInfo &hit, const Scene& scene);
	virtual void tracePhoton(LightPath &lp, const Scene &scene) {}
};


class SquareLight : public AreaLight, public AASquare
{
public:
	SquareLight();
	virtual ~SquareLight();

	// cut off public access to this, since we always want material to be LuminusMaterius
	virtual void setMaterial(Material *material) {}

	virtual void preCalc();
	
	virtual Vector3 sampleLight(const HitInfo &hit, const Scene& scene);
	virtual void tracePhoton(LightPath &lp, const Scene &scene) {}
};

class RectLight : public AreaLight, public AARect
{
public:
	RectLight();
	virtual ~RectLight();

	// cut off public access to this, since we always want material to be LuminusMaterius
	virtual void setMaterial(Material *material) {}

	virtual void preCalc();

	virtual Vector3 sampleLight(const HitInfo &hit, const Scene& scene);
	virtual void tracePhoton(LightPath &lp, const Scene &scene);
};
#endif // CSE168_AREALIGHT_H_INCLUDED
